package net.whzjkj.gateway.core.config;

import com.alibaba.fastjson.JSONObject;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import javax.annotation.Resource;
import java.net.InetSocketAddress;
import java.util.Map;

/**
 * @description: Netty配置类
 * @author: Mr.Hu
 * @create: 2018-11-05 15:32
 **/
@Slf4j
@Configuration
@EnableConfigurationProperties(value = NettyProperties.class)
public class NettyConfig {
    @Resource
    private NettyProperties properties;
    @Resource
    private ThreadPoolTaskExecutor threadPoolExecutor;
    @Resource
    private NioEventLoopGroup bossGroup;
    @Resource
    private NioEventLoopGroup workerGroup;

    private InetSocketAddress socketAddress;
    private Map<ChannelOption<?>, Object> channelOptions;

    protected ChannelInitializer<? extends Channel> channelInitializer;

    public void setPort(int port) {
        properties.setPort(port);
    }
    /**
     * 获取Boss线程组
     * @return
     */
    public NioEventLoopGroup getBossGroup() {
        if (null == bossGroup) {
            if (0 >= properties.bossThreadCount) {
                bossGroup = new NioEventLoopGroup();
            } else {
                bossGroup = bossGroup();
            }
        }
        return bossGroup;
    }

    /**
     * 获取Worker线程组
     * @return
     */
    public NioEventLoopGroup getWorkerGroup() {
        if (null == workerGroup) {
            if (0 >= properties.workerThreadCount) {
                workerGroup = new NioEventLoopGroup();
            } else {
                workerGroup = workerGroup();
            }
        }
        return workerGroup;
    }

    public synchronized InetSocketAddress getSocketAddress() {
        if (null == socketAddress) {
            socketAddress = new InetSocketAddress(properties.port);
        }
        return socketAddress;
    }

    public void setSocketAddress(InetSocketAddress socketAddress) {
        this.socketAddress = socketAddress;
    }

    public Map<ChannelOption<?>, Object> getChannelOptions() {

        return channelOptions;
    }

    public void setChannelOptions(Map<ChannelOption<?>, Object> channelOptions) {
        this.channelOptions = channelOptions;
    }

    @Bean(name = "bossGroup", destroyMethod = "shutdownGracefully")
    @ConditionalOnMissingBean(name = "bossGroup")
    public NioEventLoopGroup bossGroup(){
        NioEventLoopGroup bossGroup = new NioEventLoopGroup(properties.bossThreadCount,threadPoolExecutor.getThreadPoolExecutor());
        return bossGroup;
    }

    @Bean(name = "workerGroup", destroyMethod = "shutdownGracefully")
    @ConditionalOnMissingBean(name = "workerGroup")
    public NioEventLoopGroup workerGroup(){
        NioEventLoopGroup workerGroup = new NioEventLoopGroup(properties.workerThreadCount,threadPoolExecutor.getThreadPoolExecutor());
        return workerGroup;
    }

}
